use anyhow::Result;
use rand::Rng;
use std::thread;
use std::time::Duration;
use template::metrics::atomic::AmapMetrics;

const N: usize = 10;
const M: usize = 10;

fn main() -> Result<()> {
    let metrics = AmapMetrics::new(&[
        "call.thread.worker.0",
        "call.thread.worker.1",
        "call.thread.worker.2",
        "call.thread.worker.3",
        "call.thread.worker.4",
        "call.thread.worker.5",
        "call.thread.worker.6",
        "call.thread.worker.7",
        "call.thread.worker.8",
        "call.thread.worker.9",
        "req.page.1",
        "req.page.2",
        "req.page.3",
        "req.page.4",
    ]);

    for idx in 0..N {
        task_worker(idx, metrics.clone())?; //Arc::clone(&metrics.data)
    }

    for _ in 0..M {
        request_worker(metrics.clone())?;
    }

    loop {
        thread::sleep(Duration::from_millis(1000));
        println!("{metrics:?}");
    }

    // Ok(())
}

fn task_worker(idx: usize, metrics: AmapMetrics) -> Result<()> {
    thread::spawn(move || {
        loop {
            let mut rng = rand::rng();
            let sleep_time = rng.random_range(1..9);
            //do long term stuff
            thread::sleep(Duration::from_millis(sleep_time));
            metrics.inc(format!("call.thread.worker.{idx}").as_str())?;
        }
        #[allow(unreachable_code)]
        Ok::<_, anyhow::Error>(())
    });
    Ok(())
}

fn request_worker(metrics: AmapMetrics) -> Result<()> {
    thread::spawn(move || {
        loop {
            let mut rng = rand::rng();
            thread::sleep(Duration::from_millis(rng.random_range(50..800)));
            let page = rng.random_range(1..5);
            metrics.inc(format!("req.page.{page}").as_str())?;
        }
        #[allow(unreachable_code)]
        Ok::<_, anyhow::Error>(())
    });
    Ok(())
}
